﻿//#if INFO_DISPLAY
//#else
//#define INFO_DISPLAY
//#endif
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HelperTool_WHW
{



    /*  调用方法说明，必读
        调用方法：
        1、在要调用的地方（如WinForm中），添加一个初始化方法SerialPortInit()，方法中包括
        1.1 实例化SerialPortHelper 如 mySPhelper=new SerialPortHelper(string or comombox or enum);
        1.2 添加接收回调  mySPhelper.m_sp.DataReceived += M_sp_DataReceived;
        1.3 M_sp_DataReceived在回调中处理接收到的内容
        1.4 发送内容（如有需要）

        2、退出时，反初始化（-= 去掉对应的回调，和第1步中的 += 对应）

        如下示例
            初始化
            public void SerialPortInit()
            {
                try
                {
                      mySPhelper = new SerialPortHelper(cbx_sp_portName_1, cbx_sp_baudRate_1, cbx_sp_dataBits_1, cbx_sp_checkOut_1, cbx_sp_stopBits_1);
                      mySPhelper.m_sp.DataReceived += M_sp_DataReceived;
                    //MessageDisplay("串口已打开");
                }
                catch (System.Exception ex)
                {
                    LogNetHelper.WriteLog(ex);
                }                       
            }

            内容接受处理
               private void M_sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                //string receiveData= spHelper.m_sp.ReadLine();//有换行符且是字符串时，可换此方式读取
                byte[] receiveBytes =new byte[spHelper.m_sp.BytesToRead];

                spHelper.m_sp.Read(receiveBytes,0,receiveBytes.Length);
                string receiveStr = "";
                if (rbnReturnString.Checked)//以字符串方式接收
                {
                    receiveStr = Encoding.Default.GetString(receiveBytes);
                }
                else
                {
                    receiveStr = BitConverter.ToString(receiveBytes).Replace('-',' ');//以16进制方式接收
                };
                InfoDisplay.Display(receiveStr, receiveStr);
            }
            catch (System.Exception ex)
            {
                LogNetHelper.WriteLog(ex);
            }
        }

           发送示例
           if (rbnSendString.Checked)//字符串发送
            {
                spHelper.SendBytes(tbx_send_context.Text.Trim());
            }
            else
            {
               spHelper.Send( spHelper.HexStringToBytes(tbx_send_context.Text.Trim(), splitChar.space));//16进制发送
            }

        16进制与字符串的相互转换 : 字符串转16进制
         byte[] temp = Encoding.UTF8.GetBytes(oldSendTxt);
         newSendTxt = BitConverter.ToString(temp).Replace("-"," ");

        16进制与字符串的相互转换 : 16进制转字符串
         newSendTxt = Encoding.UTF8.GetString(spHelper.HexStringToBytes(oldSendTxt,splitChar.space));
 */

    //特别说明：如果接收和发送有乱码（有中文、用串口助手测试时）
    //可能是用的编码格式不一样，本帮助类用的是UTF8，串口助手用的是default，请根据实际要求更改编码格式
    public class SerialPortHelper
    {
        #region proprety

        public SerialPort m_sp;
        private string m_portName;
        private int m_baudRate;
        private int m_dataBits;
        private string m_checkOut;
        private string m_stopBits;
        private e_checkOut m_e_checkOut;
        private e_stopBit m_e_stopBits;

        private bool m_isInit = false;

        public bool isDisplayInfo = true;

        /// <summary>
        /// 串口号
        /// </summary>
        public string PortName_s
        {
            get
            {
                return m_portName;
            }

            set
            {
                m_portName = value;
            }
        }
        /// <summary>
        /// 波特率
        /// </summary>
        public int BaudRate_s
        {
            get
            {
                return m_baudRate;
            }

            set
            {
                m_baudRate = value;
            }
        }
        /// <summary>
        /// 数据位
        /// </summary>
        public int DataBits_s
        {
            get
            {
                return m_dataBits;
            }

            set
            {
                m_dataBits = value;
            }
        }
        /// <summary>
        /// 校验位
        /// </summary>
        public string CheckOut_s
        {
            get
            {
                return m_checkOut;
            }

            set
            {
                m_checkOut = value;
            }
        }
        /// <summary>
        /// 停止位
        /// </summary>
        public string StopBits_s
        {
            get
            {
                return m_stopBits;
            }

            set
            {
                m_stopBits = value;
            }
        }
        /// <summary>
        /// enum 校验位
        /// </summary>
        public e_checkOut E_checkOut
        {
            get
            {
                return m_e_checkOut;
            }

            set
            {
                m_e_checkOut = value;
            }
        }
        /// <summary>
        /// enum 停止位
        /// </summary>
        public e_stopBit E_stopBits
        {
            get
            {
                return m_e_stopBits;
            }

            set
            {
                m_e_stopBits = value;
            }
        }

        public bool IsOpen
        {
            get { return m_sp.IsOpen; }
        }

        public bool IsInit
        {
            get
            {
                return m_isInit;
            }

            set
            {
                m_isInit = value;
            }
        }

        #endregion

        #region field

        //public _receiveDataProc receiveDataProc;

        #endregion

        #region Constructor

        public SerialPortHelper()
        {
            IsInit = false;
        }

        public SerialPortHelper(string portname, int baudrate, int databit, string checkout, string stopbit)
        {
            m_sp = new SerialPort();
            m_sp.PortName = portname;
            m_sp.BaudRate = baudrate;
            m_sp.DataBits = databit;
            paritySetup(checkout);
            stopBitSetup(stopbit);
            m_sp.NewLine = "\r\n";

            IsInit = true;
        }

        public SerialPortHelper(string portname, int baudrate, int databit, e_checkOut checkout, e_stopBit stopbit)
        {
            m_sp = new SerialPort();
            m_sp.PortName = portname;
            m_sp.BaudRate = baudrate;
            m_sp.DataBits = databit;
            paritySetup(checkout);
            stopBitSetup(stopbit);
            m_sp.NewLine = "\r\n";

            IsInit = true;
        }

        public SerialPortHelper(ComboBox portname, ComboBox baudrate, ComboBox databit, ComboBox checkout, ComboBox stopbit)
        {
            try
            {
                m_sp = new SerialPort();
                m_sp.PortName = portname.SelectedItem.ToString();
                m_sp.BaudRate = Convert.ToInt32(baudrate.SelectedItem);
                m_sp.DataBits = Convert.ToInt32(databit.SelectedItem);
                paritySetup(checkout.SelectedItem.ToString());
                stopBitSetup(stopbit.SelectedItem.ToString());
                m_sp.NewLine = "\r\n";
                m_sp.Encoding = Encoding.Unicode;
                //IsInit = true;
                IsInit = Open();
            }
            catch (System.Exception ex)
            {
                InfoTips($"串口初始化失败：{ex.Message}", $"serialPort Constructor failed：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                IsInit = false;
            }

        }

        #endregion

        /// <summary>
        /// 信息提示（每个帮助类都加这个，是为了引用单个类和引用多个类时，能共用）
        /// 这种由于有多个判断，会增加时间开销，如果你确定了用哪种显示方式
        /// 且不会再更改，可把本方法注释掉，把下面注释掉的方法启用
        /// </summary>
        /// <param name="chinese">中文提示</param>
        /// <param name="english">英文提示</param>
        private void InfoTips(string chinese, string english)
        {
            if (isDisplayInfo)
            {
                if (InfomationDisplay.isQueue_info)
                {
                    if (InfomationDisplay.isChinese_info)
                    {
                        InfomationDisplay.bc_message_list.Add(chinese);
                    }
                    else
                    {
                        InfomationDisplay.bc_message_list.Add(english);
                    }
                }
                else
                {
                    InfomationDisplay.Display?.Invoke(chinese, english);
                }
            }
            else
            {
                LogNetHelper.WriteLog(chinese);
            }
        }
        /// <summary>
        /// 直接显示
        /// </summary>
        /// <param name="chinese"></param>
        /// <param name="english"></param>
        //private void InfoTips(string chinese, string english)
        //{
        //    if (isDisplayInfo)
        //    {
        //        InfoDisplay.Display?.Invoke(chinese, english);
        //    }
        //    else
        //    {
        //        LogNetHelper.WriteLog(chinese);
        //    }
        //}
        #region method
        /// <summary>
        /// 将enum对应的内容转换成校验位
        /// </summary>
        /// <param name="checkout">校验位对应的enum</param>
        /// <returns>设置成功返回true，否则返回false</returns>
        public bool paritySetup(e_checkOut checkout)
        {
            try
            {
                //None  Even  Odd  Mark m_space
                switch (checkout)
                {
                    case e_checkOut.None:
                        m_sp.Parity = Parity.None;
                        break;
                    case e_checkOut.Even:
                        m_sp.Parity = Parity.Even;
                        break;
                    case e_checkOut.Odd:
                        m_sp.Parity = Parity.Odd;
                        break;
                    case e_checkOut.Mark:
                        m_sp.Parity = Parity.Mark;
                        break;
                    case e_checkOut.Space:
                        m_sp.Parity = Parity.Space;
                        break;
                    default:
                        m_sp.Parity = Parity.None;
                        break;
                }
                return true;
            }
            catch (System.Exception ex)
            {
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 将None  Even  Odd  Mark m_space转换成对应的校验位
        /// </summary>
        /// <param name="checkout">None\Even\Odd\Mark\m_space</param>
        /// <returns>设置成功返回true，否则返回false</returns>
        public bool paritySetup(string checkout)
        {
            try
            {
                //None  Even  Odd  Mark space
                switch (checkout)
                {
                    case "None":
                        m_sp.Parity = Parity.None;
                        break;
                    case "Even":
                        m_sp.Parity = Parity.Even;
                        break;
                    case "Odd":
                        m_sp.Parity = Parity.Odd;
                        break;
                    case "Mark":
                        m_sp.Parity = Parity.Mark;
                        break;
                    case "Space":
                        m_sp.Parity = Parity.Space;
                        break;
                    default:
                        m_sp.Parity = Parity.None;
                        break;
                }
                return true;
            }
            catch (System.Exception ex)
            {
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 将enum对应的内容转换成停止位
        /// </summary>
        /// <param name="checkout">停止位对应的enum</param>
        /// <returns>设置成功返回true，否则返回false</returns>
        public bool stopBitSetup(e_stopBit stopbit)
        {
            try
            {
                //None  Even  Odd  Mark m_space
                switch (stopbit)
                {
                    case e_stopBit.one:
                        m_sp.StopBits = System.IO.Ports.StopBits.One;
                        break;
                    case e_stopBit.onePointFive:
                        m_sp.StopBits = System.IO.Ports.StopBits.OnePointFive;
                        break;
                    case e_stopBit.two:
                        m_sp.StopBits = System.IO.Ports.StopBits.Two;
                        break;
                    default:
                        m_sp.StopBits = System.IO.Ports.StopBits.One;
                        break;
                }
                return true;
            }
            catch (System.Exception ex)
            {
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 将One/OnePointFive/Two 或者（1、1.5、2）转换成对应停止位
        /// </summary>
        /// <param name="checkout">One/OnePointFive/Two或者（1、1.5、2） </param>
        /// <returns>设置成功返回true，否则返回false</returns>
        public bool stopBitSetup(string stopbit)
        {
            try
            {
                switch (stopbit)
                {
                    case "One":
                        m_sp.StopBits = System.IO.Ports.StopBits.One;
                        break;
                    case "1":
                        m_sp.StopBits = System.IO.Ports.StopBits.One;
                        break;
                    case "OnePointFive":
                        m_sp.StopBits = System.IO.Ports.StopBits.OnePointFive;
                        break;
                    case "1.5":
                        m_sp.StopBits = System.IO.Ports.StopBits.OnePointFive;
                        break;
                    case "Two":
                        m_sp.StopBits = System.IO.Ports.StopBits.Two;
                        break;
                    case "2":
                        m_sp.StopBits = System.IO.Ports.StopBits.Two;
                        break;
                    default:
                        m_sp.StopBits = System.IO.Ports.StopBits.One;
                        break;
                }
                return true;
            }
            catch (System.Exception ex)
            {
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }
        #endregion

        #region opreate

        public static string[] Init()
        {
            try
            {
                return SerialPort.GetPortNames();
            }
            catch (System.Exception ex)
            {
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 打开串口，对应参数已设置好
        /// </summary>
        /// <returns>打开</returns>
        public bool Open()
        {
            try
            {
                if (IsInit)
                {
                    InfoTips($"[{m_sp.PortName}] 串口已打开 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                      $"[{m_sp.PortName}] serial port opened [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return true;
                }
                //停止位选择1.5的时候会报 参数错误，原因为 (Windows配置原因)
                //MSDN描述，当数据位为6、7、8位时，停止位只能配置成1或2位；同样当数据位为5位时，停止位只能为1或1.5位
                m_sp.Open();
                if (m_sp.IsOpen)
                {
                    InfoTips($"[{m_sp.PortName}] 串口已打开 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                        $"[{m_sp.PortName}] serial port opened [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return true;
                }
                else
                {
                    InfoTips($"{m_sp.PortName} 串口没有打开，请检查", $"{m_sp.PortName} The serial port is not open，please check");
                    return false;
                }
            }
            catch (System.Exception ex)
            {
                InfoTips($"[{m_sp.PortName}] 串口打开失败：{ex.Message}", $"[{m_sp.PortName}] failed to open the serial port：{ex.Message}");
                LogNetHelper.WriteLog("Windows下，当数据位为6、7、8位时，停止位只能配置成1或2位；同样当数据位为5位时，停止位只能为1或1.5位");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 打开串口(enum)，打开前再设置一遍
        /// </summary>
        /// <param name="portname">串口号</param>
        /// <param name="baudrate">波特率</param>
        /// <param name="databit">数据位</param>
        /// <param name="checkout">校验位(enum)</param>
        /// <param name="stopbit">停止位(enum)</param>
        /// <returns>如果成功打开，返回true，否则返回false</returns>
        public bool Open(string portname, int baudrate, int databit, e_checkOut checkout, e_stopBit stopbit)
        {
            try
            {
                if (string.IsNullOrEmpty(portname))
                {
                    LogNetHelper.WriteLog("串口号不能为空");
                    return false;
                }
                m_sp.PortName = portname;
                m_sp.BaudRate = baudrate;
                m_sp.DataBits = databit;
                paritySetup(checkout);
                stopBitSetup(stopbit);
                m_sp.NewLine = "\r\n";
                return Open();
            }
            catch (System.Exception ex)
            {
                InfoTips($"[{m_sp.PortName}] 串口打开失败：{ex.Message}", $"[{m_sp.PortName}] failed to open the serial port：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }


        /// <summary>
        /// 打开串口，打开前再设置一遍
        /// </summary>
        /// <param name="portname">串口号</param>
        /// <param name="baudrate">波特率</param>
        /// <param name="databit">数据位</param>
        /// <param name="checkout">校验位</param>
        /// <param name="stopbit">停止位</param>
        /// <returns>如果成功打开，返回true，否则返回false</returns>
        public bool Open(string portname, int baudrate, int databit, string checkout, string stopbit)
        {
            try
            {
                m_sp.PortName = portname;
                m_sp.BaudRate = baudrate;
                m_sp.DataBits = databit;
                paritySetup(checkout);
                stopBitSetup(stopbit);
                m_sp.NewLine = "\r\n";
                return Open();
            }
            catch (System.Exception ex)
            {
                InfoTips($"[{m_sp.PortName}] 串口打开失败：{ex.Message}", $"[{m_sp.PortName}] failed to open the serial port：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns>关闭成功返回true，否则返回false</returns>
        public bool Close()
        {
            try
            {
                if (m_sp.IsOpen)
                {
                    //m_sp.DataReceived -= new SerialDataReceivedEventHandler(receiveDataProc);
                    m_sp.Close();
                    IsInit = false;
                }
                else
                {
                    InfoTips($"[{m_sp.PortName}] 串口没有打开", $"[{m_sp.PortName}] the serial port is not open");
                    return true;
                }
                if (m_sp.IsOpen)
                {
                    InfoTips($"[{m_sp.PortName}] 串口没有正常关闭", $"[{m_sp.PortName}] the serial port is not closed properly！！！");
                    return false;
                }
                else
                {
                    InfoTips($"[{m_sp.PortName}] 串口已关闭", $"[{m_sp.PortName}] serial port is closed");
                    return true;
                }
            }
            catch (System.Exception ex)
            {
                IsInit = true;
                InfoTips($"[{m_sp.PortName}] 串口关闭失败：{ex.Message}", $"[{m_sp.PortName}] failed to close the serial port：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 发送字符串
        /// </summary>
        /// <param name="context">要发送的字符串</param>
        /// <returns>发送成功返回true，否则返回false</returns>
        public bool Send(string context)
        {
            try
            {
                if (!m_sp.IsOpen)
                {
                    Open();
                }
                if (!m_sp.IsOpen)
                {
                    LogNetHelper.WriteLog($"{m_sp.PortName}  串口没有打开");
                    InfoTips($"[{m_sp.PortName}] 串口没有打开 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                       $"[{m_sp.PortName}] serial port is not open [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return false;
                }
                if (string.IsNullOrEmpty(context))
                {
                    InfoTips($"[{m_sp.PortName}] 发送的内容，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                      $"[{m_sp.PortName}] can send empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return false;
                }

                m_sp.Write(context);
                return true;
            }
            catch (System.Exception ex)
            {
                InfoTips($"[{m_sp.PortName}] 串口发送失败 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]" + $"  出错原因：{ex.Message}",
                      $"[{m_sp.PortName}] serial port is not open [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]" + $"  error：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }


        /// <summary>
        /// 发送16进制字符串
        /// </summary>
        /// <param name="context">要发送的16进制字符串</param>
        /// <returns>发送成功返回true，否则返回false</returns>
        public bool Send(string HexString, char splitChar)
        {
            try
            {
                if (!m_sp.IsOpen)
                {
                    Open();
                }
                if (!m_sp.IsOpen)
                {
                    LogNetHelper.WriteLog($"{m_sp.PortName}  串口没有打开");
                    InfoTips($"[{m_sp.PortName}] 串口没有打开 ", $"[{m_sp.PortName}] serial port is not open ");
                    return false;
                }
                if (string.IsNullOrEmpty(HexString))
                {
                    InfoTips($"[{m_sp.PortName}] 发送的内容，不能为空 ", $"[{m_sp.PortName}] can send empty ");
                    return false;
                }
                byte[] sendBytes = HexStringToBytes(HexString, splitChar);
                if (sendBytes == null)
                {
                    InfoTips($"[{m_sp.PortName}] 发送不成功[16进制转化成字节数组出错，请检查16进制内容及分隔符] ",
                        $"[{m_sp.PortName}] Sending failed [Error converting hexadecimal to byte array, please check hexadecimal content and separator ");
                    return false;
                }
                m_sp.Write(sendBytes, 0, sendBytes.Length);
                return true;
            }
            catch (System.Exception ex)
            {
                InfoTips($"[{m_sp.PortName}] 串口发送失败：{ex.Message}", $"[{m_sp.PortName}] serial port send failed ：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 发送字节数组（如果收发的内容不一致，请检查字符集用的是否相同，本帮助类用的是UTF8）
        /// </summary>
        /// <param name="context">要发送的字节数组</param>
        /// <returns>发送成功返回true，否则返回false</returns>
        public bool Send(byte[] context)
        {
            try
            {
                if (!m_sp.IsOpen)
                {
                    Open();
                }
                if (!m_sp.IsOpen)
                {
                    LogNetHelper.WriteLog($"{m_sp.PortName}  串口没有打开");
                    InfoTips($"[{m_sp.PortName}] 串口没有打开 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                       $"[{m_sp.PortName}] serial port is not open [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return false;
                }
                if (context == null || context.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 发送的内容，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                     $"[{m_sp.PortName}] can send empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return false;
                }
                m_sp.Write(context, 0, context.Length);
                return true;
            }
            catch (System.Exception ex)
            {
                InfoTips($"[{m_sp.PortName}] 串口发送失败 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]" + $"  出错原因：{ex.Message}",
                      $"[{m_sp.PortName}] serial port is not open [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]" + $"  error：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 发送字节数组（如果收发的内容不一致，请检查字符集用的是否相同，本帮助类用的是UTF8）
        /// </summary>
        /// <param name="context">要发送的字节数组</param>
        /// <returns>发送成功返回true，否则返回false</returns>
        public bool SendBytes(string context)
        {
            try
            {
                if (!m_sp.IsOpen)
                {
                    Open();
                }
                if (!m_sp.IsOpen)
                {
                    LogNetHelper.WriteLog($"{m_sp.PortName}  串口没有打开");
                    InfoTips($"[{m_sp.PortName}] 串口没有打开 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                       $"[{m_sp.PortName}] serial port is not open [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return false;
                }
                if (context == null || context.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 发送的内容，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                     $"[{m_sp.PortName}] can send empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return false;
                }
                byte[] sendbytes = Encoding.UTF8.GetBytes(context);
                if (sendbytes == null || sendbytes.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 发送的内容，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                    $"[{m_sp.PortName}] can send empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return false;
                }
                m_sp.Write(sendbytes, 0, sendbytes.Length);
                return true;
            }
            catch (System.Exception ex)
            {
                InfoTips($"[{m_sp.PortName}] 串口发送失败 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]" + $"  出错原因：{ex.Message}",
                      $"[{m_sp.PortName}] serial port is not open [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]" + $"  error：{ex.Message}");
                LogNetHelper.WriteLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 16进制字符串转字节数组
        /// </summary>
        /// <param name="HexString">16进制字符串内容</param>
        /// <param name="splitChar">16字符串分隔符，通常为空格、英文逗号、中心横线、下划线等</param>
        /// <returns></returns>
        public byte[] HexStringToBytes(string HexString, char splitChar)
        {
            try
            {
                string[] tempStrArray = HexString.Split(splitChar);
                byte[] temp = new byte[tempStrArray.Length];
                for (int i = 0; i < tempStrArray.Length; i++)
                {
                    temp[i] = Convert.ToByte(tempStrArray[i], 16);
                }
                return temp;
            }
            catch (Exception ex)
            {
                InfoTips($"16进制字符串转字节数组出错：{ex.Message}",
                      $"Error in converting hexadecimal string to byte array：{ ex.Message}");
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }
        /// <summary>
        /// 16进制字符串转字节数组
        /// </summary>
        /// <param name="HexString">16进制字符串内容</param>
        /// <param name="splitChar">16字符串分隔符，通常为空格、英文逗号、中心横线、下划线等</param>
        /// <returns>转换后的字节数组</returns>
        public byte[] HexStringToBytes(string HexString, splitChar split)
        {
            try
            {
                char c_splitChar = ' ';
                switch (split)
                {
                    case splitChar.space:
                        c_splitChar = ' ';
                        break;
                    case splitChar.comma:
                        c_splitChar = ',';
                        break;
                    case splitChar.underline:
                        c_splitChar = '_';
                        break;
                    case splitChar.middleLine:
                        c_splitChar = '-';
                        break;
                    default:
                        c_splitChar = ' ';
                        break;
                }
                string[] tempStrArray = HexString.Split(c_splitChar);
                byte[] temp = new byte[tempStrArray.Length];
                for (int i = 0; i < tempStrArray.Length; i++)
                {
                    temp[i] = Convert.ToByte(tempStrArray[i], 16);
                }
                return temp;
            }
            catch (Exception ex)
            {
                InfoTips($"16进制字符串转字节数组出错：{ex.Message}",
                      $"Error in converting hexadecimal string to byte array：{ ex.Message}");
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 字符串转16进制字符串
        /// </summary>
        /// <param name="str">字符串内容</param>
        /// <param name="splitChar">16字符串分隔符，通常为空格、英文逗号、中心横线、下划线等</param>
        /// <returns>返回的16进制字符串</returns>
        public string StringToHexString(string str, splitChar split)
        {
            try
            {
                char c_splitChar = ' ';
                switch (split)
                {
                    case splitChar.space:
                        c_splitChar = ' ';
                        break;
                    case splitChar.comma:
                        c_splitChar = ',';
                        break;
                    case splitChar.underline:
                        c_splitChar = '_';
                        break;
                    case splitChar.middleLine:
                        c_splitChar = '-';
                        break;
                    default:
                        c_splitChar = ' ';
                        break;
                }

                if (string.IsNullOrEmpty(str))
                {
                    InfoTips($"[{m_sp.PortName}] 要转换的字符串，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                  $"[{m_sp.PortName}] string can not be empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return null;
                }
                byte[] temp = Encoding.UTF8.GetBytes(str);
                if (temp == null || temp.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 要转换的字节数组，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                    $"[{m_sp.PortName}] byte array can not be empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return null;
                }
                return BitConverter.ToString(temp).Replace('-', c_splitChar);
            }
            catch (Exception ex)
            {
                InfoTips($"字符串转16进制字符串出错：{ex.Message}",
                      $"Error in converting string to hexadecimal string：{ ex.Message}");
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 字符串转16进制字符串
        /// </summary>
        /// <param name="str">字符串内容</param>
        /// <param name="splitChar">16字符串分隔符，通常为空格、英文逗号、中心横线、下划线等</param>
        /// <returns>返回的16进制字符串</returns>
        public string StringToHexString(string str, char split)
        {
            try
            {
                if (string.IsNullOrEmpty(str))
                {
                    InfoTips($"[{m_sp.PortName}] 要转换的字符串，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                  $"[{m_sp.PortName}] string can not be empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return null;
                }
                byte[] temp = Encoding.UTF8.GetBytes(str);
                if (temp == null || temp.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 要转换的字节数组，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                    $"[{m_sp.PortName}] byte array can not be empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return null;
                }
                return BitConverter.ToString(temp).Replace('-', split);
            }
            catch (Exception ex)
            {
                InfoTips($"字符串转16进制字符串出错：{ex.Message}",
                      $"Error in converting string to hexadecimal string：{ ex.Message}");
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }
        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bt">要转换的字节数组</param>
        /// <param name="split">16字符串分隔符，通常为空格、英文逗号、中心横线、下划线等</param>
        /// <returns>返回的16进制字符串</returns>
        public string BytesToHexString(byte[] bt, char split)
        {
            try
            {
                if (bt == null || bt.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 要转换的字节数组，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                    $"[{m_sp.PortName}] byte array can not be empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return null;
                }
                return BitConverter.ToString(bt).Replace('-', split);
            }
            catch (Exception ex)
            {
                InfoTips($"字节数组转16进制字符串出错：{ex.Message}",
                      $"Error in converting byte array to hexadecimal string：{ ex.Message}");
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bt">要转换的字节数组</param>
        /// <param name="split">16字符串分隔符，通常为空格、英文逗号、中心横线、下划线等</param>
        /// <returns>返回的16进制字符串</returns>
        public string BytesToHexString(byte[] bt, splitChar split)
        {
            try
            {
                char c_splitChar = ' ';
                switch (split)
                {
                    case splitChar.space:
                        c_splitChar = ' ';
                        break;
                    case splitChar.comma:
                        c_splitChar = ',';
                        break;
                    case splitChar.underline:
                        c_splitChar = '_';
                        break;
                    case splitChar.middleLine:
                        c_splitChar = '-';
                        break;
                    default:
                        c_splitChar = ' ';
                        break;
                }

                if (bt == null || bt.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 发送的内容，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                    $"[{m_sp.PortName}] can send empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return null;
                }
                return BitConverter.ToString(bt).Replace('-', c_splitChar);
            }
            catch (Exception ex)
            {
                InfoTips($"字节数组转16进制字符串出错：{ex.Message}",
                      $"Error in converting byte array to hexadecimal string：{ ex.Message}");
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }

        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bt">要转换的字节数组</param>
        /// <param name="split">16字符串分隔符，通常为空格、英文逗号、中心横线、下划线等</param>
        /// <returns>返回的16进制字符串</returns>
        public string BytesToString(byte[] bt)
        {
            try
            {
                if (bt == null || bt.Length < 1)
                {
                    InfoTips($"[{m_sp.PortName}] 发送的内容，不能为空 [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]",
                    $"[{m_sp.PortName}] can send empty [ {m_sp.BaudRate},{m_sp.DataBits},{m_sp.Parity},{m_sp.StopBits} ]");
                    return null;
                }
                return Encoding.UTF8.GetString(bt);
            }
            catch (Exception ex)
            {
                InfoTips($"字节数组转字符串出错：{ex.Message}",
                      $"Error in converting byte array to string：{ ex.Message}");
                LogNetHelper.WriteLog(ex);
                return null;
            }
        }
        #endregion
    }
    public enum splitChar
    {
        space = 0,
        comma,
        underline,
        middleLine
    }
    public enum e_checkOut
    {
        None = 0,
        Even,
        Odd,
        Mark,
        Space
    }

    public enum e_stopBit
    {
        one = 0,
        onePointFive,
        two
    }
}
